package cliente.TwiterApiCliente;

import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import cliente.responsehandler.xml.XmlUserDetailsResponseHandler;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import cliente.domain.User;

/**
 * This class is a simple demonstration of how to use Apache HttpClient to perform HTTP requests to Twitter's
 * REST API and how to use a XmlPullParser to parse the resulting response into an object.
 */
public class TwitterApiClient {

    private String un, pw, tweet, userSearch;

    private HttpClient httpClient;

    public TwitterApiClient() {
        this.init();
    }

    public void setLogin(String un, String pw){
        this.un = un;
        this.pw = pw;
    }

    public void setTweet(String tweet){
        this.tweet = tweet;
    }

    public void setSearchUser(String user){
        this.userSearch = user;
    }

    public void init() {
        this.httpClient = new DefaultHttpClient();
    }

    public void terminate() {
        this.httpClient.getConnectionManager().shutdown();
    }

    /**
     * Perform a GET to "http://twitter.com/users/show.xml?screen_name=dougw" (show user info for 'dougw') and
     * present the message body, without parsing it.
     *
     * This method will print an XML document.
     */
    public void doRequestWithoutParsing() {
        /*
         * TODO 1:
         * Create a new HttpGet() instance, passing "http://twitter.com/users/show.xml?screen_name=dougw" as
         * constructor argument
         */
        HttpGet request = new HttpGet("http://twitter.com/users/show.xml?screen_name=bacalhauMolhado");


        // BasicResponseHandler is a pre-defined handler that parses the body of a response into a String object.
        // It comes with HttpClient.
        BasicResponseHandler responseHandler = new BasicResponseHandler();

        String result;
        try {
            /*
             * TODO 2:
             * Call execute() method on this.httpClient, passing as arguments the request and the responseHandler
             */
            result = this.httpClient.execute(request, responseHandler);
        } catch (IOException e) {
            System.err.println("Failed to execute GET to " + request.getURI());
            e.printStackTrace();
            return;
        }

        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " XML) ---------------");
        System.out.println(result);
        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " XML) ---------------\n\n");
    }

    /**
     * Do the same request as above, but requesting JSON response.
     */
    public void doJsonRequestWithoutParsing() {
        /*
         * TODO 3:
         * Create a new HttpGet() instance, but this time request the JSON version of the document.
         * To request in JSON format, replace ".xml" with ".json"
         */
        HttpGet request = new HttpGet("http://twitter.com/users/show.json?screen_name=bacalhauMolhado");
        BasicResponseHandler responseHandler = new BasicResponseHandler();

        String result;
        try {
            result = this.httpClient.execute(request, responseHandler);
        } catch (IOException e) {
            System.err.println("Failed to execute GET to " + request.getURI());
            e.printStackTrace();
            return;
        }

        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " JSON) ---------------");
        System.out.println(result);
        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " JSON) ---------------\n\n");
    }

    /**
     * Do the same as "doJsonRequestWithoutParsing()" but this time provide credentials.
     * Study this example as it will be useful for you when posting/deleting tweets and other operations that
     * require authentication.
     *
     * *** IMPORTANT WARNING ***
     * Twitter supports two authentication mechanisms: OAuth and Basic.
     * While OAuth is far safer, Basic is far simpler.
     *
     * This method uses Basic authentication which is nothing more than a Base64 encode of a
     * concatenation between username and password -> Base64.encode(user:password)
     *
     * This is a *VERY* unsafe method (just google for base 64 decoders and you'll see how easy it is to encode/decode).
     * You are highly advised not to use your real account while doing this assignment (you can share dummy accounts
     * with your colleagues in order to avoid spamming Twitter with disposable accounts).
     */
    public void doJsonRequestWithCredentialsWithoutParsing() {
        String username = this.un;
        String password = this.pw;
        String credentials = new BASE64Encoder().encode((username + ":" + password).getBytes());

        HttpGet request = new HttpGet("http://twitter.com/users/show.json?screen_name=bacalhauMolhado");
        // Notice how this request has an header that others didn't
        /*
         * TODO 4:
         * Create a new header for the request, by calling setHeader() on the request instance.
         * This header is a Authorization header (pass "Authorization" as first parameter to setHeader())
         * As content (second parameter), pass a String with the content "Basic <credentials>" (use the credentials
         * String declared above)
         */
        // request.setHeader(...);
        BasicResponseHandler responseHandler = new BasicResponseHandler();

        String result;
        try {
            result = this.httpClient.execute(request, responseHandler);
        } catch (IOException e) {
            System.err.println("Failed to execute GET to " + request.getURI());
            e.printStackTrace();
            return;
        }

        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " JSON) ---------------");
        System.out.println(result);
        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " JSON) ---------------\n\n");
    }

    /**
     * Do a request to "http://twitter.com/users/show.xml?screen_name=dougw" which is a "show user" request,
     * parse the result using XmlPullParser and then display it to the user.
     */
    public void doRequest() {
        HttpGet request = new HttpGet("http://twitter.com/users/show.xml?screen_name=bacalhauMolhado");
        // Check out the class XmlUserDetailsResponseHandler
        ResponseHandler<User> responseHandler = new XmlUserDetailsResponseHandler();

        User user;
        try {
            user = this.httpClient.execute(request, responseHandler);
        } catch (IOException e) {
            System.err.println("Failed to execute GET to " + request.getURI());
            e.printStackTrace();
            return;
        }

        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " PARSED) ---------------");
        // show the object filled after parsing the request
        System.out.println(user);
        // show the last tweet property of the user
        System.out.println(user.getLastTweet());
        System.out.println("--- Twitter User Status request (GET " + request.getURI() + " PARSED) ---------------\n\n");
    }

//    public static void main(String[] args) {
//        TwitterApiClient demo = new TwitterApiClient();
//
//        // initialise
//        demo.init();
//
//        // comment these out in turns for a better reading
//        // do a request without parsing, showing the XML response
//        demo.doRequestWithoutParsing();
//        // do the exact same request without parsing, but showing JSON instead
//        demo.doJsonRequestWithoutParsing();
//        // do the same request, but providing credentials
//        demo.doJsonRequestWithCredentialsWithoutParsing();
//        // finally, do the request (XML) and parse it, showing the parsed content
//        demo.doRequest();
//
//        // clear resources
//        demo.terminate();
//    }
}
